﻿using System.Reflection;
using System.Runtime.InteropServices;
using welog.core.Utilities;

namespace welog.core;

public class WelogFileAttribute:Attribute
{
    public string SelectionName { get; set; }
    public WelogFileAttribute(string selectionName="default")
    {
        this.SelectionName = selectionName;
    }
}

public class SysConfig
{
    
    [WelogFile]
    public string BaseDir { get; set; } = "./welog";

    [WelogFile]
    public bool AutoSave { get; set; } = true;

    [WelogFile]
    public string TempletePath { get; set; } = "./Templete/welog.md";
    
    private static string configSavePath = "";
    private const string configSaveName = "welog.config";
    private const string defaultSectionName = "File";
    private static IniParser IniReader = null;
    
    /// <summary>
    /// 初始化配置文件
    /// </summary>
    static SysConfig()
    {
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
        {//Linux
            configSavePath = Path.Combine("~/.config",configSaveName);
        }
        else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {//Windows
            configSavePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),configSaveName);
        }
        else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
        {//OSX
        }
        IniReader = new IniParser(configSavePath);
    }
    
     public SysConfig()
    {
        if (!File.Exists(configSavePath))
        {
           using(var myfile= File.Create(configSavePath)){
           }
            this.Save();
        }
        this.Read();
    }
    

    /// <summary>
    /// 保存配置文件
    /// </summary>
    /// <returns></returns>
    public bool Save()
    {
        this.GetProperty(x=>
        { 
            var attr = x.GetCustomAttribute(typeof(WelogFileAttribute));
            var welogattr=attr as WelogFileAttribute;
            if(welogattr==null)
                return;
            IniReader.AddSetting(welogattr.SelectionName,x.Name,x.GetValue(this).ToString());
        });
        
        IniReader.SaveSettings();
        
        return true;
    }

    public bool Read()
    {
        this.GetProperty(x=>
        {
            var attr = x.GetCustomAttribute(typeof(WelogFileAttribute));
            var welogattr=attr as WelogFileAttribute;
            if(welogattr==null)
                return;
            var sectionName = welogattr.SelectionName;
            this.SetPropertyValue(this,x.Name,IniReader.GetSetting(sectionName,x.Name)); 
        });

        return true;
    }
    
    /// <summary>
    /// 通过.NET反射动态调用SetValue方法给属性PropertyInfo赋值
    /// </summary>
    /// <param name="obj">对象实例</param>
    /// <param name="propertyName">属性名称</param>
    /// <param name="sValue">字符类型的数值</param>
    private void SetPropertyValue(object obj, string propertyName, string sValue)
    {
        PropertyInfo p = obj.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
        if (p != null)
        {
            object dynmicValue;
      
            if (p.PropertyType.IsArray)//数组类型,单独处理
            {
                p.SetValue(obj, sValue, null);
            }
            else
            {
                //根据属性类型动态转换属性的值
                if (String.IsNullOrEmpty(sValue))//空值
                    dynmicValue = p.PropertyType.IsValueType ? Activator.CreateInstance(p.PropertyType) : null;//值类型
                else
                    dynmicValue = System.ComponentModel.TypeDescriptor.GetConverter(p.PropertyType).ConvertFromString(sValue.ToString());//创建对象
         
                //调用属性的SetValue方法赋值
                p.SetValue(obj, dynmicValue, null);
            }
        }
    }

    public void GetProperty(Action<PropertyInfo> readOrWriteIni)
    {
        var propertyList = this.GetType().GetProperties();
        foreach (var property in propertyList)
        {
            readOrWriteIni(property);
        }
    }
}